package dynamic.util;

import org.mybatis.generator.api.ConnectionFactory;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.JDBCConnectionFactory;
import org.mybatis.generator.internal.ObjectFactory;
import org.mybatis.generator.internal.db.DatabaseIntrospector;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class PhysicTableInfoReader {

    private final JDBCConnectionConfiguration jdbcConnectionConfiguration;
    public PhysicTableInfoReader(JDBCConnectionConfiguration jdbcConnectionConfiguration) {
     this.jdbcConnectionConfiguration =jdbcConnectionConfiguration;
    }

    private  Configuration getConfig() {
        Configuration config  =  new Configuration();

        Context context =  new Context(ModelType.CONDITIONAL);
        context.setId("ttTables");
        context.setTargetRuntime("MyBatis3");
        context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);

        JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = getJavaModelGeneratorConfiguration();
        context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);

        SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = getSqlMapGeneratorConfiguration();
        context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);

        JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = getJavaClientGeneratorConfiguration();
        context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);

        config.addContext(context);
        return config;
    }



    private  JavaModelGeneratorConfiguration getJavaModelGeneratorConfiguration() {
        JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
        javaModelGeneratorConfiguration.setTargetPackage("com.example.business.test");
        javaModelGeneratorConfiguration.setTargetProject("./src/main/java");
        javaModelGeneratorConfiguration.addProperty("enableSubPackages","false");
        javaModelGeneratorConfiguration.addProperty("trimStrings","true");
        return javaModelGeneratorConfiguration;

    }


//    <javaClientGenerator type="XMLMAPPER"
//    targetPackage="com.example.mapper"
//    targetProject="./src/main/java">
//            <!-- enableSubPackages:是否让schema作为包的后缀 -->
//            <property name="enableSubPackages" value="false" />
//        </javaClientGenerator>



    private   JavaClientGeneratorConfiguration getJavaClientGeneratorConfiguration() {
        JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
        javaClientGeneratorConfiguration.setTargetPackage("com.example.business.test");
        javaClientGeneratorConfiguration.setTargetProject("./src/main/java");
        javaClientGeneratorConfiguration.setConfigurationType("MAPPER");
        javaClientGeneratorConfiguration.addProperty("enableSubPackages","false");
        return javaClientGeneratorConfiguration;
    }

    private  SqlMapGeneratorConfiguration getSqlMapGeneratorConfiguration(){
        SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
        sqlMapGeneratorConfiguration.setTargetPackage("com.example.business.test.mapper");
        sqlMapGeneratorConfiguration.setTargetProject("./src/main/resources");
        sqlMapGeneratorConfiguration.addProperty("enableSubPackages","false");
        return sqlMapGeneratorConfiguration;
    }


    public  List<IntrospectedTable> introspectedTableList(String tableName) throws SQLException {
        Context context = getConfig().getContext("ttTables");
        DefaultShellCallback callback = new DefaultShellCallback(true);
        List<String> warnings = new ArrayList<>();
        TableConfiguration tableConfiguration =  new TableConfiguration(context);
        tableConfiguration.setTableName(tableName);
        context.addTableConfiguration(tableConfiguration);

        Connection connection = getConnection(context);

        JavaTypeResolver javaTypeResolver = ObjectFactory
                .createJavaTypeResolver(context, warnings);
        DatabaseIntrospector databaseIntrospector = new DatabaseIntrospector(
                context, connection.getMetaData(), javaTypeResolver, warnings);

        List<IntrospectedTable> list = databaseIntrospector.introspectTables(tableConfiguration);
        //context.introspectTables( new NullProgressCallback(), warnings,null);
        return list;
    }

    public static   void main(String[] args) throws SQLException {
        JDBCConnectionConfiguration jdbcConnectionConfiguration =  new JDBCConnectionConfiguration();
        jdbcConnectionConfiguration.setConnectionURL("jdbc:mysql://localhost:3306/tt");
        jdbcConnectionConfiguration.setDriverClass("com.mysql.cj.jdbc.Driver");
        jdbcConnectionConfiguration.setUserId("root");
        jdbcConnectionConfiguration.setPassword("root");

        PhysicTableInfoReader physicTableInfoReader = new PhysicTableInfoReader(jdbcConnectionConfiguration);

        List<IntrospectedTable> list =  physicTableInfoReader.introspectedTableList("table_t");
        System.out.println(list);
    }
    private  Connection getConnection(Context context ) throws SQLException {
        ConnectionFactory connectionFactory;
        if (context.getJdbcConnectionConfiguration() != null) {
            connectionFactory = new JDBCConnectionFactory(context.getJdbcConnectionConfiguration());
        } else {
            connectionFactory = ObjectFactory.createConnectionFactory(context);
        }
        return connectionFactory.getConnection();
    }

    
}
